﻿using System;
using Echo.Context.UltiProNet.Contexts;
using Echo.Core.Common;
using Echo.Core.TestAbstraction.WebUITest.MbUnit;
using Echo.Models.UltimateSoftware;
using Echo.Models.UltimateSoftware.WebUITest.MbUnit;
using MbUnit.Framework;

////*************************************************************************************************************************************
////Created by: Bryan Wexler (SWAT)
////Date created: 08/18/2010
////Modified by: David Mello (Echo Conversion)
////Date modified: 07/12/2013
////Reason: Echo conversion and refactor logic based on new functionality and tests elsewhere overlapping coverage.
////*************************************************************************************************************************************

namespace Echo.Automation.Payroll.W2_Print_Approval
{
    [TestFixture]
    [Author("David Mello", "david_mello@ultimatesoftware.com")]
    [Category("W2 Print Approval")]
    [Release("10.7.1")]
    [Header("Config")]
    [Config(".NET")]
    public class YeW2ApprovalConfirmation : MbUnitAutomatedTest
    {
        UltiPro ultiPro;
        UltiProDatabaseContext database;

        [FixtureSetUp]
        public void FixtureSetUp()
        {
            this.ultiPro = Launch<UltiPro>();
            this.database = Init<UltiProDatabaseContext>();
            this.database.Company = ConfigDatabase("ULTIPRO_SB340");
            this.database.Company.AddRollBack("paw2ApprovalDates");
            this.database.Company.AddRollBack("paw2Approvals");

            // Insert record into paw2ApprovalDates to enable print approval.
            this.database.Company.Execute("DELETE FROM paw2ApprovalDates WHERE paaYear IN (2008, 2009)");
            this.DeleteShippingPreference("TAX4");
            this.database.Company.Execute(string.Format(
                "INSERT INTO paw2ApprovalDates (paaFinalApprovalDate, paaYear) VALUES ('{0}',2008)",
                DateTime.Now.AddDays(1).ToShortDateString()));

            // Login and click Reporting > W2 Print Approval.
            this.ultiPro.Pages.Login.LoginAs("BlackM", "password", Config.LanguageCode);
            this.ultiPro.Menu.Reporting.Click(link => link.W2PrintApproval);
            
            // Proceed to the TAX4 group and fill in the required fields on the page.
            this.ultiPro.Pages.W2PrintApprovalSummary.W2PrintApprovalSummaryGrid.Row(row => row.TaxGroupLink, "TAX4").Click(link => link.TaxGroupLink);
            this.FillInMiscRequiredFields();
        }

        [FixtureTearDown]
        public void FixtureTearDown()
        {
            DeleteShippingPreference("TAX4");
            this.database.Company.RollBackDatabase();
            this.ultiPro.Browser.Quit();
        }

        /// <summary>
        /// Verify the Approval Confirmation lightbox is displayed and contains the correct Approval Confirmation message.
        /// </summary>
        [Test(Order = 0)]
        public void ConfirmLightboxHasImportantMessages()
        {
            // Given all required fields are filled in.
            this.ultiPro.Pages.W2PrintApprovalDetail.Click(cb => cb.PrintApprovalStatusCheckBox);

            // When I click Save.
            this.ultiPro.Pages.W2PrintApprovalDetail.ButtonBar.Click(b => b.Save);

            // Then the Important Message lightbox should appear with header.
            this.ultiPro.Pages.W2PrintApprovalDetail.ConfirmBox.Is(h2 => h2.Message, "innerHtml", ultiPro.Localization.Strings.Important_Message.ToTitleCase());

            // And the second paragraph will contain message. (first paragraph is covered in W2DeliveryMethodTests.cs)
            var expectedMessage =
                string.Format(
                    "You will not be able to process any additional payroll transactions for the {0} calendar year once you select OK.",
                    this.database.Company.GetValue("select top 1 paayear from paW2approvaldates order by paayear desc"));

            this.ultiPro.Pages.W2PrintApprovalDetail.ConfirmBox.Like(p => p.ImportantMessageText.ToJQuery().find("p").eq(1), "innerHtml", expectedMessage);

            // And the third paragraph will contain message.
            this.ultiPro.Pages.W2PrintApprovalDetail.ConfirmBox.Like(
                p => p.ImportantMessageText.ToJQuery().find("p").eq(2),
                "innerHtml",
                "Select Cancel if additional payroll transactions are required for this tax group.");

            // And the fourth paragraph will contain message.
            expectedMessage =
                string.Format(
                    "Note: UltiPro will automatically approve this tax group for Form W-2 printing if approval is not completed by {0}.",
                    DateTime.Now.AddDays(1).ToString("MM/dd/yyyy"));

            this.ultiPro.Pages.W2PrintApprovalDetail.ConfirmBox.Like(
                p => p.ImportantMessageText.ToJQuery().find("p").eq(3),
                "innerHtml",
                expectedMessage);
        }

        /// <summary>
        /// Verify the initial lightbox button state is OK (disabled) and Cancel (enabled).
        /// </summary>
        [Test(Order = 10)]
        public void LightboxContainsButtons()
        {
            // Given the important message lightbox is open from the previous test.

            // Then there will be a checkbox (state unchecked) with message.
            this.ultiPro.Pages.W2PrintApprovalDetail.ConfirmBox.Is(cb => cb.ImportantMessageCheckBoxLabel, "innerHtml", ultiPro.Localization.Strings.If_you_have_read_the_above_information_select_the_checkbox_to_proceed_and_then_click_OK_period);
            this.ultiPro.Pages.W2PrintApprovalDetail.ConfirmBox.NotSelected(cb => cb.CheckboxConfirm);

            // And a disabled OK button.
            this.ultiPro.Pages.W2PrintApprovalDetail.ConfirmBox.Like(b => b.YesButton, "class", "buttonResizableDisabled");
            this.ultiPro.Pages.W2PrintApprovalDetail.ConfirmBox.Is(b => b.YesButton.ToJQuery().find("span"), "innerHtml", ultiPro.Localization.Strings.OK.ToUpperCase());

            // And an enabled Cancel button.
            this.ultiPro.Pages.W2PrintApprovalDetail.ConfirmBox.NotLike(b => b.NoButton, "class", "buttonResizableDisabled");
            this.ultiPro.Pages.W2PrintApprovalDetail.ConfirmBox.Is(b => b.NoButton.ToJQuery().find("span"), "innerHtml", ultiPro.Localization.Strings.Cancel);
        }

        /// <summary>
        /// Verify the OK button loses the disabled class when the confirm checkbox is clicked.
        /// </summary>
        [Test(Order = 20)]
        public void OkButtonEnabledWhenConfirmChecked()
        {
            // Given the important message lightbox is open from the previous test.

            // When I click the Confirm checkbox.
            this.ultiPro.Pages.W2PrintApprovalDetail.ConfirmBox.Click(cb => cb.CheckboxConfirm);

            // Then the OK button will enable.
            this.ultiPro.Pages.W2PrintApprovalDetail.ConfirmBox.NotLike(b => b.YesButton, "class", "buttonResizableDisabled");
        }

        /// <summary>
        /// Verifies the Cancel button dismisses the lightbox without saving changes to the database.
        /// </summary>
        [Test(Order = 30)]
        public void CancelClosesLightboxWithoutSavingApproval()
        {
            // Given the important message lightbox is open from the previous test.

            // When I click the Cancel/No button.
            this.ultiPro.Pages.W2PrintApprovalDetail.ConfirmBox.Click(b => b.NoButton);

            // Then the lightbox will disappear.
            this.ultiPro.Pages.W2PrintApprovalDetail.ConfirmBox.NotVisibleOrNotExists(p => p.Message);
            // And no approval will be saved.
            Assert.AreEqual("0", this.database.Company.GetValue("SELECT COUNT(*) FROM paw2approvals WHERE pawTaxGroup = 'TAX4'"));
            // And the approved checkbox on the details page should still be checked.
            this.ultiPro.Pages.W2PrintApprovalDetail.Selected(cb => cb.PrintApprovalStatusCheckBox);
        }

        /// <summary>
        /// Check the database to ensure the confirmation flag has been set as well as who set the flag and when it was set.
        /// </summary>
        [Test(Order = 40)]
        public void OkButtonSavesApproval()
        {
            // Given we are on the approval details page with required fields still filled in.

            // When I click the Save button checkbox.
            this.ultiPro.Pages.W2PrintApprovalDetail.ButtonBar.Click(b => b.Save);

            // Then the lightbox will reappear without the confirm selected from the previous step.
            this.ultiPro.Pages.W2PrintApprovalDetail.ConfirmBox.NotSelected(cb => cb.CheckboxConfirm);
            
            // And when recheck the confirm and click OK.
            this.ultiPro.Pages.W2PrintApprovalDetail.ConfirmBox.Click(cb => cb.CheckboxConfirm);
            this.ultiPro.Pages.W2PrintApprovalDetail.ConfirmBox.Click(b => b.YesButton);

            // Then the lightbox will be closed.
            this.ultiPro.Pages.W2PrintApprovalDetail.ConfirmBox.NotVisibleOrNotExists(b => b.YesButton);
            // And the approval record will be persisted to the database.
            Assert.AreEqual("1", 
                this.database.Company.GetValue(
                "SELECT COUNT(*) FROM paw2approvals WHERE pawTaxGroup = 'TAX4' AND pawChangedBy = 'BlackM' AND pawChangedName = ' Michael A Black ' AND pawApprovedBy = 'BlackM' and pawYear = 2008"));
        }

        private void DeleteShippingPreference(string taxGroup)
        {
            this.database.Company.Execute(string.Format("DELETE FROM paw2approvals WHERE pawTaxGroup = '{0}'", taxGroup));
        }

        private void FillInMiscRequiredFields()
        {
            this.ultiPro.Pages.W2PrintApprovalDetail.Set(
                x => x.PrimaryEmailAddressTextBox, "w2@preferencetesting.org");
            this.ultiPro.Pages.W2PrintApprovalDetail.Set(x => x.CopyRecipientsDropDown, "ARTRIPL1", SelectOption.Value);
        }
    }
}
